<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        const requestsLimit = (list, limit, asyncHandle) => {
            return new Promise(resolve => {
                let _limit = limit;
                let recordList = []; // 记录异步操作
                let index = 0;
                let listCopy = [].concat(list);
                let asyncList = []; // 正在进行的所有并发异步操作


                const asyncFunc = () => {
                    while (_limit--) {
                        const data = listCopy.shift()
                        if (data) asyncList.push(asyncHandle(data, index++));
                    }

                    Promise.all(asyncList).then(response => {
                        // 监听并记录每一次请求的结果
                        recordList = recordList.concat(response.filter(item => item));


                        if (listCopy.length !== 0) {
                            _limit = limit;
                            asyncList = [];
                            asyncFunc() // 数组还未迭代完，递归继续进行迭代
                        } else {
                            // 所有并发异步操作都完成后，本次并发控制迭代完成，返回记录结果
                            resolve(recordList)
                        }
                    })
                }


                asyncFunc()
            })
        }


    </script>
</body>

</html>